package com.ncloud.web;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ncloud.common.conf.FileConfig;
import com.ncloud.common.exception.UserException;

@RestController
public class FileUploadController {

	@Autowired
	private FileConfig fileConfig;

	@RequestMapping("/file")
	public String file() {
		return "/file";
	}

	@RequestMapping("/mutifile")
	public String mutifile() {
		return "/mutifile";
	}

	/**
	 * 文件上传具体实现方法;
	 * 
	 * @param file
	 * @return
	 */
	@RequestMapping("/upload")
	@ResponseBody
	public JSONObject handleFileUpload(HttpServletRequest request, @RequestParam("file") MultipartFile file) {
		JSONObject json = new JSONObject();
		if (!file.isEmpty()) {
			String path = getProjectPath();
			File pathFile = new File(path);
			if (!pathFile.exists() && !pathFile.isDirectory()) {
				pathFile.mkdirs();
			}
			String fileName = path + file.getOriginalFilename();
			File targetFile = new File(fileName);

			if (targetFile.exists() && !targetFile.isDirectory()) {
				throw new UserException("4001", "附件已经存在");
			}
			try {
				file.transferTo(targetFile);
			} catch (IllegalStateException | IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			json.put("code", "0000");
			json.put("path", fileName);
		} else {
			// return "上传失败，因为文件是空的.";
		}
		return json;
	}

	@RequestMapping("/delete")
	@ResponseBody
	public JSONObject deleteFile(HttpServletRequest request) {
		JSONObject json = new JSONObject();
		String fileName = request.getParameter("filePath");
		System.out.println(fileName);
		File targetFile = new File(fileName);
		boolean result = targetFile.delete();
		json.put("result", result);
		return json;
	}

	@RequestMapping("/download")
	@ResponseBody
	public ResponseEntity<byte[]> download(String filePath, HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		File file = new File(filePath);
		HttpHeaders httpHeaders = new HttpHeaders();
		String filename = new String(file.getName().getBytes("UTF-8"), "ISO-8859-1");
		httpHeaders.setContentDispositionFormData("attachment", filename);
		httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), httpHeaders, HttpStatus.CREATED);
	}

	private String getProjectPath() {
		Date currentTime = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
		String dateString = formatter.format(currentTime);
		String path = fileConfig.pathDir + File.separatorChar + dateString + File.separatorChar;

		return path;
	}

	/**
	 * 多文件具体上传时间，主要是使用了MultipartHttpServletRequest和MultipartFile
	 * 
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/batch/upload", method = RequestMethod.POST)
	public @ResponseBody JSONObject handleFileUpload(Long projectId, HttpServletRequest request) {
		JSONObject result = new JSONObject();
		result.put("code", "0000");
		String path = getProjectPath();
		File pathFile = new File(path);
		if (!pathFile.exists() && !pathFile.isDirectory()) {
			pathFile.mkdirs();
		}
		JSONArray paths = new JSONArray();
		Map<String, MultipartFile> map = ((MultipartHttpServletRequest) request).getFileMap();
		MultipartFile file = null;
		List<File> fileUploaded = new ArrayList<File>();
		for(Iterator<Map.Entry<String, MultipartFile>> it = map.entrySet().iterator();it.hasNext();) {
			Map.Entry<String, MultipartFile> entry = it.next();
			file = entry.getValue();
			JSONObject json = new JSONObject();
			if (!file.isEmpty()) {
				try {
					String fileName = path + file.getOriginalFilename();
					File targetFile = new File(fileName);
					if (targetFile.exists() && !targetFile.isDirectory()) {
						throw new UserException("4001", file.getOriginalFilename() + "已经存在");
					}
					file.transferTo(targetFile);
					json.put("fileName", file.getOriginalFilename());
					json.put("path", fileName);
					fileUploaded.add(targetFile);
				} catch (Exception e) {
					e.printStackTrace();
					for(File f : fileUploaded) {
						if(f.exists()){
							f.delete();
						}
					}
					if(e instanceof UserException){
						throw new UserException("4001", file.getOriginalFilename() + "已经存在");
					}					
				}
				paths.add(json);
			}
		}
		result.put("info", paths);
		return result;
	}
//	算了，不折腾了，将来如果大量文件名重复异常，使用MD5做区分
	private String getFileMD5(File file) throws IOException, NoSuchAlgorithmException {
		String value = null; 
		FileInputStream in = new FileInputStream(file); 
		MappedByteBuffer byteBuffer = in.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length()); 
		MessageDigest md5 = MessageDigest.getInstance("MD5"); 
		md5.update(byteBuffer); 
		BigInteger bi = new BigInteger(1, md5.digest()); 
		value = bi.toString(16);
		return value;
	}
}